﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;

namespace CNative.DBWebApiClient
{
    /// <summary>
    /// 请求类型
    /// </summary>
    public enum EnumHttpVerb
    {
        GET,
        POST,
        PUT,
        DELETE
    }

    public class MyWebClient : WebClient
    {
        private int _timeout;
        /// <summary>
        /// 超时时间(毫秒)
        /// </summary>
        public int Timeout
        {
            get
            {
                return _timeout;
            }
            set
            {
                _timeout = value;
            }
        }
        public MyWebClient()
        {
            //设置时间
            this._timeout = 60000000;
        }
        public MyWebClient(int timeout)
        {
            this._timeout = timeout;
        }
        protected override WebRequest GetWebRequest(Uri address)
        {
            var result = base.GetWebRequest(address);
            result.Timeout = this._timeout;
            return result;
        }
        #region HttpRequest GET/POST/PUT/DELETE
        /// <summary>
        /// Http (GET)
        /// </summary>
        /// <param name="url">请求URL</param>
        /// <param name="contentType">HTTP 标头的值</param>
        /// <param name="parameters">请求参数</param>
        /// <param name="headers">HTTP 标头的名称/值对的集合</param>
        /// <returns>响应内容</returns>
        public string GET(string url, string contentType = "application/json"
            , IDictionary<string, string> parameters = null, IDictionary<string, string> headers = null, string webProxyAddress = "")
        {
            return HttpRequest(EnumHttpVerb.GET, url, "", contentType, parameters, headers, webProxyAddress);
        }
        /// <summary>
        /// Http (POST)
        /// </summary>
        /// <param name="url">请求URL</param>
        /// <param name="postData">Post 数据</param>
        /// <param name="contentType">HTTP 标头的值</param>
        /// <param name="headers">HTTP 标头的名称/值对的集合</param>
        /// <returns>响应内容</returns>
        public string POST(string url, string postData, string contentType = "application/json"
            , IDictionary<string, string> headers = null, string webProxyAddress = "")
        {
            return HttpRequest(EnumHttpVerb.POST, url, postData, contentType, null, headers, webProxyAddress);
        }
        /// <summary>
        /// Http (PUT)
        /// </summary>
        /// <param name="url">请求URL</param>
        /// <param name="postData">Post 数据</param>
        /// <param name="contentType">TTP 标头的值</param>
        /// <param name="headers">HTTP 标头的名称/值对的集合</param>
        /// <returns>响应内容</returns>
        public string PUT(string url, string postData, string contentType = "application/json"
            , IDictionary<string, string> headers = null, string webProxyAddress = "")
        {
            return HttpRequest(EnumHttpVerb.PUT, url, postData, contentType, null, headers, webProxyAddress);
        }
        /// <summary>
        ///  Http (DELETE)
        /// </summary>
        /// <param name="url">请求URL</param>
        /// <param name="postData">Post 数据</param>
        /// <param name="contentType">HTTP 标头的值</param>
        /// <param name="headers">HTTP 标头的名称/值对的集合</param>
        /// <returns>响应内容</returns>
        public string DELETE(string url, string postData, string contentType = "application/json"
            , IDictionary<string, string> headers = null, string webProxyAddress = "")
        {
            return HttpRequest(EnumHttpVerb.DELETE, url, postData, contentType, null, headers, webProxyAddress);
        }
        public string HttpRequest(EnumHttpVerb method, string url, string postData, string contentType = "application/json"
            , IDictionary<string, string> parameters = null, IDictionary<string, string> headers = null, string webProxyAddress = "")
        {
            //设置请求参数
            if (parameters != null && parameters.Count > 0)
            {
                url += (url.Contains("?") ? "&" : "?") + BuildQuery(parameters, Encoding.UTF8);
            }
            using (var request = new WebClient())
            {
                if (headers == null) headers = new Dictionary<string, string>();
                headers.Add("Content-Type", contentType);
                //设置HTTP 标头的名称/值对的集合
                if (headers != null && headers.Count > 0)
                {
                    BuildHeader(request, headers);
                }
                //设置代理
                if (!string.IsNullOrEmpty(webProxyAddress))
                {
                    var proxy = new WebProxy(webProxyAddress);//IP地址 port为端口号 代理类
                    request.Proxy = proxy;
                }
                //-----------------------------------------------------------------------------
                if (!string.IsNullOrEmpty(postData) && method != EnumHttpVerb.GET)
                {
                    try
                    {
                        var bytes = Encoding.UTF8.GetBytes(postData);
                        request.Headers.Add("ContentLength", bytes.Length.ToString());

                        //创建输入流
                        byte[] responseData = request.UploadData(url, method.ToString(), bytes);
                        return Encoding.UTF8.GetString(responseData);// 解码  
                    }
                    catch (Exception ex)
                    {
                        return ex.ToString();//连接服务器失败
                    }
                }
                else
                {
                    using (var stream = request.OpenRead(url))
                    {
                        using (var reader = new System.IO.StreamReader(stream))
                            return reader.ReadToEnd();
                    }
                }
            }
        }
        private void BuildHeader(WebClient request, IDictionary<string, string> headers)
        {
            if (request == null) return;
            IEnumerator<KeyValuePair<string, string>> dem = headers.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    request.Headers[name] = value;
                }
            }
        }
        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        private string BuildQuery(IDictionary<string, string> parameters, Encoding encode = null)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;
            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name))//&& !string.IsNullOrEmpty(value)
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }
                    postData.Append(name);
                    postData.Append("=");
                    if (encode == null)
                    {
                        postData.Append(System.Web.HttpUtility.UrlEncode(value, encode));
                    }
                    else
                    {
                        postData.Append(value);
                    }
                    hasParam = true;
                }
            }
            return postData.ToString();
        }
        #endregion
    }
}
